package com.mgfireworks.mgplatform.mgadmin.stock;

import cn.hn.java.summer.db.BaseDao;
import cn.hn.java.summer.db.multiple.DataSource1;
import cn.hn.java.summer.exception.BusinessException;
import cn.hn.java.summer.utils.DateUtils;
import cn.hn.java.summer.utils.IntUtils;
import com.mgfireworks.mgplatform.comm.StringUtils;
import com.mgfireworks.mgplatform.mgadmin.constants.BooleanEnum;
import com.mgfireworks.mgplatform.mgadmin.constants.OrderState;
import com.mgfireworks.mgplatform.mgadmin.constants.OrgType;
import com.mgfireworks.mgplatform.mgadmin.product.model.Product;
import com.mgfireworks.mgplatform.mgadmin.stock.model.Order;
import com.mgfireworks.mgplatform.mgadmin.stock.model.OrderItem;
import com.mgfireworks.mgplatform.mgadmin.stock.model.Stock;
import com.mgfireworks.mgplatform.mgadmin.sys.OrganizationService;
import com.mgfireworks.mgplatform.mgadmin.sys.model.Organization;
import com.mgfireworks.mgplatform.mgadmin.user.model.User;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by af on 2017/3/26.
 *
 */
@Service
public class OrderService  extends BaseDao<DataSource1> {

    @Autowired
    OrganizationService organizationService;
    @Autowired
    StockService stockService;

    /**
     * 进货
     * @param u
     * @return
     */
    public List<Stock> getStockProductForOrder(User u,Product product){
        Organization org= organizationService.getOrganizationById(u.getOrgId());
        int orgType=-1;
        if(org.getOrgType()== OrgType.DELEGATE1.value()){
            //一级代理商取厂家库存产品
            orgType=OrgType.FACTORY.value();
        }else if(org.getOrgType()== OrgType.DELEGATE2.value()){
            //二级代理商，取所属一级代理商库存产品
            product.setOrgId(org.getParentId());
            orgType=OrgType.DELEGATE1.value();
        }
        return this.list(
            "getStockProductForOrder",
            Stock.class,
            product,
            ce().set("orgType",orgType)
        );
    }

    /**
     * 添加订单项
     * @param orderItem
     */
    @Transactional(rollbackFor = Exception.class)
    public void addOrderItem(User user,OrderItem orderItem) throws BusinessException {
        addOneOrderItem(user,orderItem);
    }

    /**
     * 添加订单项
     * @param user
     * @param orderItem
     * @throws BusinessException
     */
    private void addOneOrderItem(User user,OrderItem orderItem) throws BusinessException {
        //先查看有无未完成订单，没有则创建，有则使用原有订单
        Order order=getUnPayedOrder(user);
        List<OrderItem> items=new ArrayList<>();
        double orderAmount=0;
        boolean itemExist=false;
        if(order==null){
            //创建新订单
            order=newOrder(user);
            orderItem.setItemId(1);
        }else{
            items=getAllOrderItems(order.getOrderId());
            if(items==null || items.size()==0){
                throw new BusinessException("订单数据不完整！");
            }
            //默认递增订单项id
            orderItem.setItemId(items.get(0).getItemId()+1);
            //找到相同订单项合并
            for(OrderItem oi : items){
                if(oi.getProductId().equals(orderItem.getProductId())){
                    orderItem.setItemId(oi.getItemId());
                    orderItem.setPrice(oi.getPrice());
                    //增加数量
                    orderItem.setNum(oi.getNum() + orderItem.getNum());
                    oi.setNum(orderItem.getNum());
                    itemExist=true;
                }
                //计算总额
                orderAmount+=oi.getNum()*oi.getPrice();
            }
        }

        if(itemExist){
            //订单项存在或修改订单项，则更新
            orderItem.setOrderId(order.getOrderId());
            this.update("updateOrderItem",orderItem);
        }else{
            //获取产品库存价格
            Stock stock= stockService.getProductStock(orderItem.getStockId());
            //添加订单项
            orderItem.setOrderId(order.getOrderId());
            orderItem.setStockId(stock.getStockId());
            orderItem.setProductId(stock.getProductId());
            orderItem.setPrice(stock.getPrice());
            this.update("addOrderItem",orderItem);
            items.add(orderItem);
            //计算总额
            orderAmount+=orderItem.getNum()*orderItem.getPrice();
        }

        //加上新增项的总额
        //更新订单信息
        order.setItemCount(items.size());
        order.setOrderAmount(orderAmount);
        order.setUpdateTime(DateTime.now().toDate());
        updateOrder(order);
    }

    /**
     * 取订单信息
     * @param orderId
     * @return
     */
    public Order getOrder(String orderId){
        return this.get("getOrders",Order.class, ce().set("orderId",orderId));
    }

    /**
     * 取用户未支付的订单
     * @param user
     * @return
     */
    public Order getUnPayedOrder(User user){
        return this.get(
            "getOrders",
            Order.class,
           ce().set("userId",user.getUserId())
               .set("orderState", OrderState.UNPAID.value())
        );
    }

    /**
     * 取订单的所有订单项
     * @param orderId
     * @return
     */
    public List<OrderItem> getAllOrderItems(String orderId){
        return this.all("getOrderItemInfos",OrderItem.class,ce().set("orderId",orderId));
    }

    /**
     * 更新订单信息
     * @param order
     */
    public void updateOrder(Order order){
        this.update("updateOrder",order);
    }

    /**
     * 创建新的订单
     * @param user
     */
    public Order newOrder(User user){
        Order order=new Order();
        order.setOrderAmount(0d);
        order.setOrderState(OrderState.UNPAID.value());
        order.setOrderTime(DateTime.now().toDate());
        order.setItemCount(0);
        order.setUpdateTime(order.getOrderTime());
        order.setOrderId(newOrderId(user.getOrgId()));
        order.setOrgId(user.getOrgId());
        order.setUserId(user.getUserId());
        this.update("addStockOrder",order);
        return order;
    }

    /**
     * 取新订单号
     * @return
     */
    public String newOrderId(int orgId){
        //订单ID(4位orgId+yyMMdd+4位序号=14位)
        String orderId=this.get("getMaxStockOrderId",String.class,orgId);
        if(orderId!=null && orderId.length()==14){
            orderId=orderId.substring(10);
        }
        int index= IntUtils.parseInt(orderId,0)+1;
        orderId=StringUtils.leftPad(orgId+"",4,'0')+
                DateUtils.now("yyMMdd")+
                StringUtils.leftPad(index+"",4,'0');
        return orderId;
    }

    /**
     * 取用户订单和订单项列表
     * @param user 当前用户
     * @param order 查询项
     * @return
     */
    public List<Order> getUserOrderAndItemInfos(User user, Order order){
        order.setUserId(user.getUserId());
        List<Order> orders=this.list("getOrders",Order.class,order);
        for (Order o : orders){
            o.setOrderItemInfoList(getAllOrderItems(o.getOrderId()));
        }
        return orders;
    }

    /**
     * 结算订单
     * @param orderId
     */
    @Transactional(rollbackFor = Exception.class)
    public void checkoutOrder(String orderId, User user) throws BusinessException {
        //取订单信息
        Order order=getOrder(orderId);
        if(order==null){
            throw new BusinessException("订单不存在！");
        }
        if(order.getOrderState()!=OrderState.UNPAID.value()){
            throw new BusinessException("订单已处理！");
        }

        //取订单所有项信息
        List<OrderItem> orderItemList= getAllOrderItems(orderId);
        if(orderItemList.isEmpty()){
            throw  new BusinessException("订单项信息错误！");
        }

        for(OrderItem oi : orderItemList) {
            //1.减少出货库存
            //取库存信息,保证没有下架
            Stock stock= stockService.getStock(ce().set("stockId",oi.getStockId()));
            if(stock.getOnline()!= BooleanEnum.TRUE.value()){
                throw new BusinessException("订单产品已下架！");
            }
            //减少现有库存数
            stockService.decreaseProductStock(stock,oi.getNum());

            //2.增加进货库存
            //取原有库存
            Stock stockOld= stockService.getStock(
                    ce().set("productId",stock.getProductId())
                            .set("orgId",user.getOrgId())
            );
            if(stockOld==null) {
                //添加新的产品库存
                stockService.addNewProductStock(user, stock);
            }else {
                //增加原有产品库存
                stockService.increaseProductStock(stockOld, oi.getNum());
            }

            //设置订单状态为完成
            this.update("updateOrder",
                    ce().set("orderState",OrderState.FINISHED.value())
                        .set("orderId",orderId)
            );
        }

    }

    /**
     * 更新订单项
     * @param items
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderItems(User user, List<OrderItem> items) throws BusinessException {
        //取未支付的订单
        Order order=getUnPayedOrder(user);
        if(order==null){
            throw new BusinessException("订单信息不存在！");
        }
        //取该订单所有订单项
        List<OrderItem> oldItems=getAllOrderItems(order.getOrderId());
        if(oldItems.isEmpty() || oldItems.size()!=items.size()){
            throw  new BusinessException("订单信息不正确！");
        }

        final double[] orderAmount = {0};
        //找到每个订单项更新数量
        oldItems.stream().forEach((OrderItem item) ->{
            OrderItem findItem= items.stream().filter(
                    orderItem -> item.getProductId().equals(orderItem.getProductId())
            ).findFirst().get();
            if(findItem!=null) {
                //不用验证是否超过库存,最后提交订单时验证
                item.setNum(findItem.getNum());
                this.update("updateOrderItem", item);
            }
            //计算订单总额
            orderAmount[0] +=item.getNum()*item.getPrice();
        });

        //更新订单信息
        order.setUpdateTime(DateTime.now().toDate());
        order.setOrderAmount(orderAmount[0]);
        updateOrder(order);
    }

    /**
     * 取消订单
     * @param orderId
     */
    public void cancelOrder(String orderId) throws BusinessException {
        Order order=getOrder(orderId);
        if(order.getOrderState()!=OrderState.UNPAID.value()){
            throw new BusinessException("订单已支付，不能再取消！");
        }

        //订单状态改为已关闭
        order.setOrderState(OrderState.CLOSED.value());
        updateOrder(order);
    }
}
